package org.xmonkey.notifier;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.dom.ASTNode;
import org.xmonkey.controller.extractor.ProjectAnalysisRequest;
import org.xmonkey.notifier.model.INotifier;
import org.xmonkey.notifier.model.ISubscriber;
import org.xmonkey.notifier.model.ProjectNodeSubscriptions;
import org.xmonkey.notifier.model.ProjectVisitSubscriptions;
import org.xmonkey.notifier.model.WorkspaceSubscriptions;

/**
 * This class contains and handles all the subscriptions that X-Monkey
 * will have to address while visiting ASTs.
 * This class is the facade of X-Monkey towards other plug-ins
 * @author Jappo
 *
 */
public class SubscriptionsRegister implements INotifier {
	
	// singletone, accessible from other plug-ins
	private static final SubscriptionsRegister instance = new SubscriptionsRegister();
	
	private WorkspaceSubscriptions subscriptions;
	private ProjectVisitSubscriptions startSubscriptions;
	private ProjectVisitSubscriptions endSubscriptions;
	
	private SubscriptionsRegister(){
		// initialization
		subscriptions =	new WorkspaceSubscriptions();
		startSubscriptions = new ProjectVisitSubscriptions();
		endSubscriptions = new ProjectVisitSubscriptions();
	}
	
	public static SubscriptionsRegister getInstance(){
		return instance;
	}

	public void registerNotificationRequestFor(IProject project, int nodeType, ISubscriber client) {
		subscriptions.subscribe(project, nodeType, client);
		System.out.println(subscriptions.toString());
		
	}

	public void notifyVisit(IProject project, ASTNode node) {
		if(subscriptions.containsKey(project)){
			ProjectNodeSubscriptions projectSubscription = subscriptions.get(project);
			projectSubscription.notifyVisit(node);
		}
	}

	public void startVisitFor(IProject project) {
		if (isValidProject(project)) {
			new ProjectAnalysisRequest(project, new JobChangeListener(project));
		}
	}
	
	private boolean isValidProject(final IProject project) {
		return project != null && project.isAccessible();
	}
	
	public void registerStartNotificationRequestFor(IProject project, ISubscriber subscriber) {
		startSubscriptions.subscribe(project, subscriber);
	}

	public void registerEndNotificationRequestFor(IProject project, ISubscriber subscriber) {
		endSubscriptions.subscribe(project, subscriber);
	}

	public void removeAllSubscriptions(IProject project, ISubscriber subscriber) {
		subscriptions.removeSubscriptions(project, subscriber);
		endSubscriptions.removeSubscriptions(project, subscriber);
		startSubscriptions.removeSubscriptions(project, subscriber);
	}

	public void notifyStart(IProject project) {
		startSubscriptions.notifyStart(project);
	}

	public void notifyEnd(IProject project) {
		endSubscriptions.notifyEnd(project);
	}

	public void removeEndSubscriptions(IProject project, ISubscriber subscriber) {
		endSubscriptions.removeSubscriptions(project, subscriber);
	}

	public void removeStartSubscriptions(IProject project, ISubscriber subscriber) {
		startSubscriptions.removeSubscriptions(project, subscriber);
	}

}
